package com.gm.baseplatform.core.jdbc;

import java.io.Reader;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;


public class JDBCWrapper {
  private Connection connection = null;
  private Statement statement = null;
  private PreparedStatement preparedStatement = null;
  boolean isAutoCommit = true;
  private int fetchSize = 0;
  private int fetchDirection = ResultSet.FETCH_FORWARD;
  private DataSource ds;
  private String jdbcClassName;
  private String jdbcConnUrl;
  private String jdbcUserName;
  private String jdbcUserPasswd;
  private boolean usePool = true;

  
  public JDBCWrapper() throws NamingException, SQLException {
    String jndiName="jdbc/Ora9iDB";
    Context initContext = new InitialContext();
    Context envContext  = (Context)initContext.lookup("java:comp/env");
    DataSource ds = (DataSource)envContext.lookup(jndiName);
    connection = ds.getConnection();
  }

  
  public JDBCWrapper(String jndiName) throws NamingException, SQLException {
    Context jndiCntx = new InitialContext();
    Context envContext  = (Context)jndiCntx.lookup("java:comp/env");
    ds = (DataSource) envContext.lookup(jndiName);
    connection = ds.getConnection();
  }


  public JDBCWrapper(String className, String URL, String userName,
      String passWord) throws  SQLException,
      ClassNotFoundException {
    Class.forName(className);
    this.jdbcClassName = className;
    this.jdbcConnUrl = URL;
    this.jdbcUserName = userName;
    this.jdbcUserPasswd = passWord;
    this.usePool = false;
    connection = DriverManager.getConnection(URL, userName, passWord);
  }


  public Connection getConnection() {
    if (connection == null) {
      if (usePool)
        try {
          connection = ds.getConnection();
        } catch (SQLException e) {
          e.printStackTrace();
        }
      else
        try {
          connection = DriverManager.getConnection(this.jdbcConnUrl,
              this.jdbcUserName, this.jdbcUserPasswd);
        } catch (SQLException e1) {
          e1.printStackTrace();
        }
    }
    setAutoCommit(false);
    return connection;
  }


  public boolean isAutoCommit() {
    return isAutoCommit;
  }

  
  public void setAutoCommit(boolean b) {
    try {
      isAutoCommit = b;
      connection.setAutoCommit(b);
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }


  public void createStatement() throws SQLException {
    statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
  }


  public PreparedStatement getPreparedStatement() {
    return preparedStatement;
  }


  public void setFetchSize(int value) {
    this.fetchSize = value;
  }


  public void setFetchDirction(int value) {
    this.fetchDirection = value;
  }


  public void prepareStatement(String sql) throws SQLException {
    preparedStatement = connection.prepareStatement(sql);
  }


  public void setString(int index, String value) throws SQLException {
    preparedStatement.setString(index, value);
  }
  
  
  public void setCharacterStream(int index,Reader reader,int length)throws SQLException{
  	preparedStatement.setCharacterStream(index,reader,length);
  }


  public void setInt(int index, int value) throws SQLException {
    preparedStatement.setInt(index, value);
  }


  public void setBoolean(int index, boolean value) throws SQLException {
    preparedStatement.setBoolean(index, value);
  }


  public void setDate(int index, Date value) throws SQLException {
    preparedStatement.setDate(index, value);
  }

  
  public void setLong(int index, long value) throws SQLException {
    preparedStatement.setLong(index, value);
  }


  public void setFloat(int index, float value) throws SQLException {
    preparedStatement.setFloat(index, value);
  }


  public void setClob(int index, Clob value) throws SQLException {
    preparedStatement.setClob(index, value);
  }


  public void setObject(int index, Object value) throws SQLException {
    preparedStatement.setObject(index, value);
  }


  public void setTimestamp(int index, java.sql.Timestamp value)
      throws SQLException {
    preparedStatement.setTimestamp(index, value);
  }


  public Statement getStatement() {
    return statement;
  }


  public void clearParameters() throws SQLException {
    preparedStatement.clearParameters();
  }


  public void commit() throws SQLException {
    try {
      connection.commit();
    } catch (SQLException ex) {
      ex.printStackTrace();
      throw ex;
    }
  }


  public void rollback() throws SQLException {
    try {
      connection.rollback();
    } catch (SQLException ex) {
      ex.printStackTrace();
      throw ex;
    }
  }


  public ResultSet executeQuery(String sql) throws SQLException {
    if (statement != null) {
      statement.setFetchSize(this.fetchSize);
      statement.setFetchDirection(this.fetchDirection);
      return statement.executeQuery(sql);
    } else
      throw new SQLException ("executeQuery SQLException");
  }


  public ResultSet executeQuery() throws SQLException {
    if (preparedStatement != null) {
      preparedStatement.setFetchSize(this.fetchSize);
      preparedStatement.setFetchDirection(this.fetchDirection);
      return preparedStatement.executeQuery();
    } else
      throw new SQLException ("executeQuery SQLException");
  }


  public int executeUpdate(String sql) throws SQLException {
    int num = 0;
    if(statement==null){this.createStatement();}
    if (statement != null) {
      num = statement.executeUpdate(sql);
    }
    return num;
  }


  public int executeUpdate() throws SQLException {
    int num = 0;
    if (preparedStatement != null) {
      num = preparedStatement.executeUpdate();
    }
    return num;
  }


  public int[] doBatch(String sql) throws SQLException {
    int[] rowResult = null;
    String a;
    try {
      statement = connection.createStatement();
      java.util.StringTokenizer st = new java.util.StringTokenizer(sql, ";");
      while (st.hasMoreElements()) {
        a = st.nextToken();
        statement.addBatch(a);
      }
      rowResult = statement.executeBatch();
    } catch (SQLException ex) {
      ex.printStackTrace();
      System.out.println("dbTrans.doBatch" + ex.getMessage());
      throw ex;
    }
    return rowResult;
  }


  public void close() throws SQLException {
    try {
      if (statement != null) {
        statement.close();
        statement = null;
      }
      if (preparedStatement != null) {
        preparedStatement.close();
        preparedStatement = null;
      }
      if (connection != null) {
        connection.close();
        connection = null;
      }
    }
    catch (SQLException e) {
      throw e;
    }
  }
}